package com.example.myviewgroup;

import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;

import java.util.List;

/**
 * author: ts
 * created on: 2021/8/27 下午4:25
 * description:
 */
public class MyFlexBoxLayout extends ViewGroup {

    //子View的Margin值
    private final int mMarginLeft = 20;
    private final int mMarginRight = 20;
    private final int mMarginTop = 10;
    private final int mMarginBottom = 0;
    //超过第几行开始折叠
    public static final int mFoldLines = 2;
    //是否折叠
    public boolean mIsFold = true;

    private Boolean mFoldState;

    public boolean mIsAdd = false;

    private OnFoldChangedListener mOnFoldChangedListener;

    public MyFlexBoxLayout(Context context) {
        super(context);
    }

    public MyFlexBoxLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        //总行数
        int lines = 0;

        /**
         * 获得此ViewGroup上级容器为其推荐的宽和高，以及计算模式
         */
        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        int widthSize = MeasureSpec.getSize(widthMeasureSpec);
        int heightSize = MeasureSpec.getSize(heightMeasureSpec);

        //测量子View
        measureChildren(widthMeasureSpec, heightMeasureSpec);

        //剩余宽度
        int remainingWidth = widthSize;
        //当前行宽度
        int currentWidth = 0;
        //高度
        int height = 0;
        //当前行的最大高度
        int maxHeight = 0;
        //子View的数量
        int childCount = getChildCount();
        //发生折叠的索引
        int foldIndex = 0;
        //折叠的状态
        boolean newFoldState = false;

        for (int i = 0; i < childCount; i++) {
            //当前子View
            View childView = getChildAt(i);
            //测量子View
            measureChild(childView, widthMeasureSpec, heightMeasureSpec);
            //得到child的lp获取margin值，这里使用报错，还是直接设置吧
            //MarginLayoutParams layoutParams = (MarginLayoutParams) childView.getLayoutParams();
            //获取child的实际宽度和高度
            int childWidth = childView.getMeasuredWidth();
            //如果加上当前的item宽大于容器的宽就换行 否则不换行
            if (childWidth + mMarginLeft + mMarginRight > widthSize - currentWidth) {
                //换行
                lines++;
                if (mIsFold && lines >= mFoldLines) {
                    lines++;
                    height += maxHeight;
                    newFoldState = true;
                    remainingWidth = widthSize - mMarginRight - mMarginLeft - currentWidth;
                    break;
                }
                height += maxHeight;
                currentWidth = mMarginLeft + mMarginRight + childView.getMeasuredWidth();
            } else {
                currentWidth += mMarginLeft + mMarginRight + childView.getMeasuredWidth();
            }
            maxHeight = Math.max(childView.getMeasuredHeight() + mMarginTop + mMarginBottom, maxHeight);
            if (i == childCount - 1) {
                height += maxHeight;
                lines++;
            }
            //默认在最后一个，当可以折叠时，为break时的下标
            foldIndex = i;
            Log.d("TAG", "onMeasure: foldIndex = " + foldIndex);
        }
        System.out.println("lines" + lines);
        setMeasuredDimension(widthSize, height);
        changeFold(lines > mFoldLines, newFoldState, foldIndex, remainingWidth);
    }

    @Override
    protected void onLayout(boolean change, int l, int t, int r, int f) {
        int left = 0;
        int top = 0;
        int right;
        int bottom;

        int maxLineHeight = 0;
        int currentLineWidth = 0;

        int childCount = getChildCount();
        for (int i = 0; i < childCount; i++) {
            View childView = getChildAt(i);
            /*MarginLayoutParams layoutParams = (MarginLayoutParams) childView.getLayoutParams();
            int rightMargin = layoutParams.rightMargin;
            int leftMargin = layoutParams.leftMargin;
            int topMargin = layoutParams.topMargin;
            int bottomMargin = layoutParams.bottomMargin;*/
            if (childView.getMeasuredWidth() + mMarginLeft + mMarginRight > getMeasuredWidth() - currentLineWidth) {
                //换行
                left = mMarginLeft;
                top += maxLineHeight;
                right = left + childView.getMeasuredWidth();
                bottom = top + childView.getMeasuredHeight() + mMarginTop;

                childView.layout(left, top + mMarginTop, right, bottom);

                currentLineWidth = childView.getMeasuredWidth() + mMarginLeft + mMarginRight;
                left = right + mMarginRight;
                maxLineHeight = Math.max(childView.getMeasuredHeight() + mMarginTop + mMarginBottom, 0);
            } else {
                //不换行
                currentLineWidth += childView.getMeasuredWidth() + mMarginLeft + mMarginRight;
                maxLineHeight = Math.max(childView.getMeasuredHeight() + mMarginTop + mMarginBottom, maxLineHeight);

                left += mMarginLeft;
                right = left + childView.getMeasuredWidth();
                bottom = top + childView.getMeasuredHeight() + mMarginTop;

                childView.layout(left, top + mMarginTop, right, bottom);

                left = right + mMarginRight;
            }
        }
    }

    /**
     * 折叠状态改变回调
     *
     * @param canFold        是否可以折叠
     * @param newFoldState   新的折叠状态
     * @param index          下标
     * @param remainingWidth 剩余空间
     */
    private void changeFold(boolean canFold, boolean newFoldState, int index, int remainingWidth) {
        if (mFoldState == null || mFoldState != newFoldState) {
            if (canFold) {
                mFoldState = newFoldState;
            }
            if (mOnFoldChangedListener != null) {
                mOnFoldChangedListener.onFoldChange(canFold, newFoldState, index, remainingWidth);
            }
        }
        //解决添加时下拉不会更新的问题
        if (mIsAdd){
            if (mOnFoldChangedListener != null) {
                mOnFoldChangedListener.onFoldChange(canFold, newFoldState, index, remainingWidth);
            }
            mIsAdd = false;
        }
    }

    /**
     * 设置折叠状态回调
     *
     * @param listener
     */
    public void setOnFoldChangedListener(OnFoldChangedListener listener) {
        mOnFoldChangedListener = listener;
    }

    public interface OnFoldChangedListener {


        /**
         * 折叠状态时时回调
         *
         * @param canFold      是否可以折叠，true为可以折叠，false为不可以折叠
         * @param fold         当前折叠状态，true为折叠，false为未折叠
         * @param index        当前显示的view索引数量
         * @param surplusWidth 折叠状态下 剩余空间
         */
        void onFoldChange(boolean canFold, boolean fold, int index, int surplusWidth);
    }
}
